package syntaxcolor.v4.syntaxcolor.rule;

import org.eclipse.swt.custom.StyleRange;

import syntaxcolor.v4.syntaxcolor.scanner.Scanner;
import syntaxcolor.v4.syntaxcolor.token.Token;

/**
 * 开始字符串和结束字符串符合规则，中间的字符任意，属于模式规则，像字符串，多行注释，单行注释等都属于这种规则
 * 
 * @author wyl
 */
public class PatternRule implements IRule {

	private String name = "string";

	private String startStr = "\"";

	private String endStr[] = new String[] { "\n", "\"" };

	private char escapChar = '\\';

	private StyleRange style;

	public PatternRule(String name, String startStr, String[] endStr,
			char escapChar, StyleRange style) {
		super();
		this.name = name;
		this.startStr = startStr;
		this.endStr = endStr;
		this.escapChar = escapChar;
		this.style = style;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see syntaxcolor.v2.IRule#evaluate(syntaxcolor.v2.Scanner)
	 */
	public Token evaluate(Scanner scanner) {
		int offset = scanner.getOffset();
		int startIndex = 0;
		int ch = scanner.read();
		// 查看是否符合起始字符串
		while (startIndex < startStr.length()
				&& ch == startStr.charAt(startIndex)) {
			ch = scanner.read();
			startIndex++;
		}
		// 部分匹配起始字符串，不符合规则
		if (startIndex < startStr.length()) {
			scanner.setOffset(offset);
			return null;
		}
		while (ch > 0) {
			// 跳过转义字符
			if (ch == escapChar) {
				ch = scanner.read();
				ch = scanner.read();
				continue;
			}
			int subOffset = scanner.getOffset();
			int subCh = ch;
			// 开始查找结束字符串
			for (String s : endStr) {
				startIndex = 0;
				while (startIndex < s.length() && s.charAt(startIndex) == subCh) {
					subCh = scanner.read();
					startIndex++;
				}
				// 找到符合结束字符串的字符串，得到分段
				if (startIndex == s.length()) {
					scanner.unread();
					return new Token(offset, scanner.getOffset() - offset, name);
				}
				scanner.setOffset(subOffset);
				subCh = ch;
			}
			ch = scanner.read();
		}
		// 字符串结束，所有的字符都属于此规则（规则字符未结束）
		return new Token(offset, scanner.getOffset() - offset, name);
	}

	public StyleRange getStyle() {
		return this.style;
	}

	public String getName() {
		return this.name;
	}
}
